ci: SHA-pin all actions + persist-credentials, add zizmor/actionlint/scorecard - #54
Conversation
…scorecard
Systematic GitHub Actions supply-chain hardening — resolves all 65 zizmor
findings across the workflows.
Pinning (unpinned-uses, 30): pin every remaining floating action to a commit
SHA, matching the repo's existing hash-pinning intent:
- actions/checkout@v6 -> @de0fac2 # v6.0.2
- Swatinem/rust-cache@v2 -> @e18b497 # v2
- actions/setup-python@v6.2.0 -> @a309ff8 # v6.2.0
- EmbarkStudios/cargo-deny-action -> @6c8f9fac # v2.0.18
- dtolnay/rust-toolchain@stable/@1.89.0 -> @29eef33 with an explicit
'with: toolchain: {stable,1.89.0}' so the SHA pin keeps the channel
(the ref no longer encodes it).
Credential hygiene (artipacked, 18): add 'persist-credentials: false' to every
checkout. No workflow pushes via git (releases use OIDC trusted-publishing;
changelog creates the Release via the API token), so this is safe throughout.
Enforcement (new workflows) to keep the above from regressing:
- zizmor.yml - workflow security audit (offline, pinned zizmor 1.25.2)
- actionlint.yml - workflow lint + shellcheck (pinned actionlint v1.7.12 via Go)
- scorecard.yml - OpenSSF Scorecard (publishes score badge + SARIF)
Verified locally: zizmor --offline clean across all 10 workflows; actionlint
clean; YAML parses. The new workflows are themselves SHA-pinned, set
persist-credentials: false, and scope GITHUB_TOKEN permissions.
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
Review Summary by QodoHarden GitHub Actions workflows: SHA-pin all actions, disable credential persistence, add security enforcement
WalkthroughsDescription• SHA-pin 30 floating actions across 10 workflows to commit SHAs - actions/checkout@v6 → @de0fac2 # v6.0.2 (10 instances) - Swatinem/rust-cache@v2 → @e18b497 # v2 (9 instances) - dtolnay/rust-toolchain → @29eef33 with explicit toolchain: input - actions/setup-python@v6.2.0 → @a309ff8 # v6.2.0 - EmbarkStudios/cargo-deny-action@v2.0.18 → @6c8f9fac # v2.0.18 • Add persist-credentials: false to all 18 checkout steps • Introduce three new enforcement workflows for supply-chain security - zizmor.yml — offline GitHub Actions security audit (pinned zizmor==1.25.2) - actionlint.yml — workflow lint + shellcheck validation (pinned actionlint v1.7.12) - scorecard.yml — OpenSSF Scorecard analysis with SARIF upload Diagramflowchart LR
A["Floating Actions<br/>v6, v2, stable"] -->|"SHA-pin to<br/>commit hashes"| B["Pinned Actions<br/>@de0fac2, @e18b497, etc."]
C["Checkout with<br/>persisted credentials"] -->|"Add persist-credentials<br/>false"| D["Checkout with<br/>no credential persistence"]
B --> E["New Enforcement<br/>Workflows"]
D --> E
E --> F["zizmor<br/>Security Audit"]
E --> G["actionlint<br/>Workflow Lint"]
E --> H["scorecard<br/>SARIF Upload"]
File Changes1. .github/workflows/actionlint.yml
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb38d68ce9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
…dex review)
Job-level permissions REPLACE the workflow-level set (omitted scopes become
none), so the analysis job's {security-events, id-token} block was dropping the
workflow-level contents: read that checkout + Scorecard need to read the repo.
Add it explicitly (matching the release workflows' publish jobs). Latent —
scorecard.yml runs only on push-to-main/schedule, not PRs, so CI didn't surface it.
What
Systematic GitHub Actions supply-chain hardening. Resolves all 65 zizmor findings across the workflows and adds three enforcement workflows so the posture cannot silently regress.
Why
Most actions were already SHA-pinned (harden-runner, upload-artifact, codeql, …) but a handful were left on floating tags, and no checkout set
persist-credentials: false. The PR bots had been flagging these one at a time; zizmor surfaces the full set in one pass.Changes
1. Pin every remaining floating action to a commit SHA (
unpinned-uses×30)actions/checkout@v6(×10)@de0fac2 # v6.0.2Swatinem/rust-cache@v2(×9)@e18b497 # v2actions/setup-python@v6.2.0@a309ff8 # v6.2.0EmbarkStudios/cargo-deny-action@v2.0.18@6c8f9fac # v2.0.18dtolnay/rust-toolchain@stable/@1.89.0@29eef33+ explicittoolchain:dtolnay/rust-toolchainis special: the channel was encoded in the ref (@stable), so pinning to a SHA requires an explicitwith: toolchain: stable(or1.89.0for the MSRV job) — matching the pattern the release workflows already use.2.
persist-credentials: falseon every checkout (artipacked×18)No workflow pushes via git (releases use OIDC trusted-publishing; the changelog job creates the Release via the API token), so dropping the persisted credential is safe everywhere. Merged into existing
with:blocks where present (e.g. changelog'sfetch-depth: 0).3. New enforcement workflows
zizmor.yml— GitHub Actions security audit (offline, pinnedzizmor==1.25.2). A future unpinned action / broad token / credential-persisting checkout fails here.actionlint.yml— workflow lint + shellcheck overrun:blocks (pinnedactionlint v1.7.12, installed via the runner's Go).scorecard.yml— OpenSSF Scorecard; publishes the score badge + SARIF to code scanning.All three are themselves SHA-pinned, set
persist-credentials: false, and scopeGITHUB_TOKEN.Verification (local)
zizmor --offline --persona=regular .github/workflows/→ No findings (all 10 workflows).actionlint .github/workflows/*.yml→ clean.Test plan
dtolnay/rust-toolchain+ explicittoolchain:inputs must still install the right channel (watch thelint,test, andmsrv (1.89.0)jobs).zizmorandactionlintjobs pass.scorecardjob runs and uploads SARIF on first run.